package com.oritsh.dicom.service;

import com.oritsh.dicom.exception.DicomException;
import com.oritsh.dicom.exception.MoveException;
import com.oritsh.dicom.scu.DicomStreamStore;
import com.oritsh.dicom.scu.GetSCU;
import com.oritsh.dicom.scu.MoveSCU;
import com.oritsh.dicom.utils.DataSetHelper;
import com.oritsh.dicom.utils.SCUFactory;
import org.dcm4che.data.Attributes;
import org.dcm4che.data.Tag;
import org.dcm4che.io.DicomInputStream;
import org.dcm4che.net.DimseRSP;
import org.dcm4che.net.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * Created by xiashenpin on 16/1/31.
 */
public class CMoveService {
    Logger logger = LoggerFactory.getLogger(CMoveService.class);

    SCUFactory scuFactory;

    DicomStreamStore dicomStreamStore;

    boolean sendAllParams = true;

    private String destination;

    public boolean isSendAllParams() {
        return sendAllParams;
    }

    public void setSendAllParams(boolean sendAllParams) {
        this.sendAllParams = sendAllParams;
    }

    public SCUFactory getScuFactory() {
        return scuFactory;
    }

    public void setScuFactory(SCUFactory scuFactory) {
        this.scuFactory = scuFactory;
    }

    public DicomStreamStore getDicomStreamStore() {
        return dicomStreamStore;
    }

    public void setDicomStreamStore(DicomStreamStore dicomStreamStore) {
        this.dicomStreamStore = dicomStreamStore;
    }

    public String getDestination() {
        return destination;
    }

    public void setDestination(String destination) {
        this.destination = destination;
    }

    public DicomInputStream cmove(String study, String series, String sop, boolean pop) throws Exception {
        DicomInputStream inputStream ;
        if (pop)
            inputStream = dicomStreamStore.pop(sop);
        else
            inputStream = dicomStreamStore.fetch(sop);
        if (inputStream != null)
            return inputStream;
        try(MoveSCU scu = (MoveSCU) scuFactory.createSCU(MoveSCU.class)){
            scu.setDestination(getDestination());

            Attributes attributes = new Attributes();
            if (isSendAllParams()) {
                DataSetHelper.putValueToDataSet(attributes, Tag.StudyInstanceUID, study);
                DataSetHelper.putValueToDataSet(attributes,Tag.SeriesInstanceUID,series);
            }
            DataSetHelper.putValueToDataSet(attributes,Tag.SOPInstanceUID,sop);
            DataSetHelper.putValueToDataSet(attributes, Tag.QueryRetrieveLevel, "IMAGE");

            DimseRSP rsp = scu.retrieve(attributes);

            int lastStatus = -1;
            while (rsp.next()) {
                Attributes command = rsp.getCommand();
                lastStatus = command.getInt(Tag.Status, -1);

                //logger.info(DataSetHelper.attributesToString(command));

                if (Status.isPending(lastStatus))
                    continue;
            }
            if (lastStatus != Status.Success) {
                logger.info(String.format("lastStatus:%x",lastStatus));
                throw new MoveException(String.format("status:%x is not success",lastStatus));
            }

            DicomInputStream dim = null;
            if (pop)
                dim = dicomStreamStore.pop(sop);
            else
                dim = dicomStreamStore.fetch(sop);
            return dim;
        }
    }
}
